package com.xujie.sportsmeeting.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xujie.sportsmeeting.dto.JudgeQueryDTO;
import com.xujie.sportsmeeting.entity.Judge;
import com.xujie.sportsmeeting.entity.SysUser;
import com.xujie.sportsmeeting.entity.SysUserRole;
import com.xujie.sportsmeeting.mapper.JudgeMapper;
import com.xujie.sportsmeeting.mapper.SysUserRoleMapper;
import com.xujie.sportsmeeting.service.JudgeService;
import com.xujie.sportsmeeting.service.SysUserService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * 裁判员服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class JudgeServiceImpl extends ServiceImpl<JudgeMapper, Judge> implements JudgeService {

    private final SysUserService sysUserService;
    private final PasswordEncoder passwordEncoder;
    private final SysUserRoleMapper sysUserRoleMapper;

    @Override
    public IPage<Judge> getJudgePage(IPage<Judge> page, JudgeQueryDTO queryDTO) {
        LambdaQueryWrapper<Judge> wrapper = new LambdaQueryWrapper<>();
        
        // 构建查询条件
        if (StringUtils.hasText(queryDTO.getWorkNumber())) {
            wrapper.like(Judge::getWorkNumber, queryDTO.getWorkNumber());
        }
        if (StringUtils.hasText(queryDTO.getRealName())) {
            wrapper.like(Judge::getRealName, queryDTO.getRealName());
        }
        if (StringUtils.hasText(queryDTO.getDepartment())) {
            wrapper.like(Judge::getDepartment, queryDTO.getDepartment());
        }
        if (StringUtils.hasText(queryDTO.getProfessionalLevel())) {
            wrapper.eq(Judge::getProfessionalLevel, queryDTO.getProfessionalLevel());
        }
        if (queryDTO.getGender() != null) {
            wrapper.eq(Judge::getGender, queryDTO.getGender());
        }
        if (queryDTO.getStatus() != null) {
            wrapper.eq(Judge::getStatus, queryDTO.getStatus());
        }
        
        // 按创建时间倒序
        wrapper.orderByDesc(Judge::getCreateTime);
        
        return page(page, wrapper);
    }

    @Override
    @Transactional
    public boolean createJudge(Judge judge) {
        // 检查工号是否已存在
        if (existsByWorkNumber(judge.getWorkNumber())) {
            throw new RuntimeException("工号已存在");
        }
        
        try {
            // 1. 检查用户名是否已存在
            LambdaQueryWrapper<SysUser> userWrapper = new LambdaQueryWrapper<>();
            userWrapper.eq(SysUser::getUsername, judge.getWorkNumber());
            SysUser existingUser = sysUserService.getOne(userWrapper);
            
            SysUser user;
            if (existingUser != null) {
                // 用户已存在，使用现有用户
                user = existingUser;
                log.info("用户名 {} 已存在，使用现有用户账号: userId={}", judge.getWorkNumber(), user.getId());
            } else {
                // 创建新用户账号
                user = new SysUser();
                user.setUsername(judge.getWorkNumber());
                user.setPassword(passwordEncoder.encode("123456")); // 默认密码
                user.setRealName(judge.getRealName());
                user.setGender(judge.getGender());
                user.setPhone(judge.getPhone());
                user.setEmail(judge.getEmail());
                user.setDepartment(judge.getDepartment());
                user.setStatus(1); // 启用
                
                boolean userCreated = sysUserService.save(user);
                if (!userCreated) {
                    throw new RuntimeException("创建用户账号失败");
                }
                log.info("成功创建新用户账号: username={}, userId={}", judge.getWorkNumber(), user.getId());
            }
            
            // 2. 设置裁判员的user_id关联
            judge.setUserId(user.getId());
            
            // 3. 保存裁判员信息
            boolean judgeCreated = this.save(judge);
            if (!judgeCreated) {
                throw new RuntimeException("创建裁判员信息失败");
            }
            
            // 4. 为裁判员用户分配"裁判员"角色 (role_id = 2)
            // 检查是否已分配裁判员角色
            LambdaQueryWrapper<SysUserRole> roleWrapper = new LambdaQueryWrapper<>();
            roleWrapper.eq(SysUserRole::getUserId, user.getId())
                      .eq(SysUserRole::getRoleId, 2L);
            SysUserRole existingRole = sysUserRoleMapper.selectOne(roleWrapper);
            
            if (existingRole == null) {
                // 还没有分配裁判员角色，进行分配
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(user.getId());
                userRole.setRoleId(2L); // 裁判员角色ID
                
                int roleAssigned = sysUserRoleMapper.insert(userRole);
                if (roleAssigned <= 0) {
                    log.warn("为裁判员用户分配角色失败: userId={}", user.getId());
                } else {
                    log.info("成功为裁判员用户分配角色: userId={}, roleId=2", user.getId());
                }
            } else {
                log.info("用户 {} 已具有裁判员角色，跳过角色分配", user.getId());
            }
            
            log.info("成功创建裁判员用户: username={}, judgeId={}, realName={}", 
                    judge.getWorkNumber(), judge.getId(), judge.getRealName());
            return true;
            
        } catch (Exception e) {
            log.error("创建裁判员失败: {}", e.getMessage(), e);
            throw new RuntimeException("创建裁判员失败: " + e.getMessage());
        }
    }

    @Override
    public boolean updateJudge(Judge judge) {
        // 检查工号是否被其他裁判员使用
        Judge existingJudge = findByWorkNumber(judge.getWorkNumber());
        if (existingJudge != null && !existingJudge.getId().equals(judge.getId())) {
            throw new RuntimeException("工号已被其他裁判员使用");
        }
        
        return updateById(judge);
    }

    @Override
    public boolean updateJudgeStatus(Long id, Integer status) {
        Judge judge = getById(id);
        if (judge == null) {
            throw new RuntimeException("裁判员不存在");
        }
        
        judge.setStatus(status);
        return updateById(judge);
    }

    @Override
    public Judge findByWorkNumber(String workNumber) {
        LambdaQueryWrapper<Judge> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Judge::getWorkNumber, workNumber);
        return getOne(wrapper);
    }

    @Override
    public Judge findByUserId(Long userId) {
        LambdaQueryWrapper<Judge> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Judge::getUserId, userId);
        return getOne(wrapper);
    }

    @Override
    public boolean existsByWorkNumber(String workNumber) {
        LambdaQueryWrapper<Judge> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Judge::getWorkNumber, workNumber);
        return count(wrapper) > 0;
    }
}
